
#ifndef __KHAN_VTY_HISTORY_HPP__
#define __KHAN_VTY_HISTORY_HPP__


#include "khan.hpp"
#include "vty.hpp"
#include <deque>


/* FIXME: 
   차후, 모든 섹션에 대한 히스토리와 섹션 별로 history 관리 */
template <typename T>
class vty_history
//:private boost::noncopyable
{
public:
    typedef typename std::deque<T>    container;
    typedef typename container::value_type value_type;
    typedef typename container::iterator iterator;
    typedef typename container::const_iterator const_iterator;
    typedef typename container::size_type  size_type;
    typedef typename container::difference_type difference_type;
    typedef typename container::reference reference;
    typedef typename container::const_reference const_reference;
    typedef typename container::pointer pointer;
    typedef typename container::const_pointer const_pointer;

    vty_history():
        _top(0), _cap(DFL_SIZE),
        _container(DFL_SIZE), _cp(-1)
    {};
    vty_history(std::size_t size):
        _top(0), _cap(DFL_SIZE),
        _container(size), _cp(-1)
    {};

    void resize() {};
    void reset() { _cp = -1; }
    void clear() { 
        PDBG(">>> container size: %d\n", _container.size());
        _top = 0; _cp = -1; _container.clear(); 
        PDBG(">>> container size: %d\n", _container.size());
    };

    std::size_t size() { return _top; };
    bool empty() { return  (_top == 0); };
    bool full() { return  (_cap == _top); };
    bool is_top() { return ((_cp+1) == _top); };
    bool is_bottom() { return ((_cp+1) == 0); };

    iterator begin() { return _container.begin(); };
    iterator end() { return _container.end(); };

    pointer linerize() { return &(_container[0]); };
    template <class InputIterator>
    void reset (InputIterator first, InputIterator last) {
        this->clear();
        iterator result = _container.begin();
        while (first != last) {
            *result++ = *first++;
            _top++;
        }
    }
    
    std::size_t current(reference cp) {
        if (empty()) return -1;
        if (is_bottom()) return -1;
        cp = _container[_cp];
        return _cp;
    };

    int prev(reference np) { 
        if (is_top()) return -1;
        //PDBG("CP: %d\n",_cp);
        np  = _container[++_cp];
        return 0;
    };

    int next(reference pp) {
        string_ptr ptr;
        if (is_bottom()) return -1;
        if (_cp == 0) return -1;
        //PDBG("CP: %d\n",(_cp-1));
        pp = _container[--_cp];
        return 0;
    }

    void pop_back() { 
        if (empty()) return;
        _top--; 
        _container.pop_back(); 
    }

    void push_back(T ptr) { 
        if (full()) return;
        _top++; 
        _container.push_back(ptr); 
    }

    void push_front(T ptr) { 
        if (full()) return;
        _top++; 
        _container.push_front(ptr); 
    }

private:
    enum { DFL_SIZE=128 };

    std::size_t _top;
    std::size_t _cap;
    container   _container;
    std::size_t    _cp;
};

#endif 
